home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
-
- #ifdef __MSDOS__
- #include <mem.h>
- #define WRITE_BINARY "wb"
- #define READ_BINARY "rb"
- #ifdef GNDIR
- #include "gndir.h"
- #endif
- #else
- #define WRITE_BINARY "w"
- #define READ_BINARY "r"
- #endif
-
- #define SEARCHBUFSIZE 0xa000U // 40K is average midi file size
-
- char trivialcheck = 0;
-
- int findchar(unsigned char* s, unsigned slen, char c)
- {
- if (memchr(s, c, slen))
- return 1;
- if (!isalpha(c))
- return 0;
- if (c >= 'a' && c <= 'z')
- return memchr(s, toupper(c), slen) != 0;
- return memchr(s, tolower(c), slen) != 0;
- }
-
- int matching(unsigned char* s, char* w, unsigned slen)
- {
- while (*w)
- {
- if (*s == 0)
- {
- if (*w == '*')
- {
- w++;
- continue;
- }
- return 0;
- }
- else if (toupper(*w) == toupper(*s))
- {
- w++;
- s++;
- slen--;
- }
- else if (*w == '#')
- {
- if (*s == 0)
- return 0;
- if (isdigit(*s))
- {
- s++;
- slen--;
- w++;
- }
- else
- return 0;
- }
- else if (*w == '?')
- {
- if (*s == 0)
- return 0;
- s++;
- slen--;
- w++;
- }
- else if (*w == '*')
- {
- while (*w == '*')
- w++;
- if (*w == 0)
- return 1;
- #ifdef SEEK_CHARACTERS
- char* p;
- for (p = w; *p; p++)
- if (strchr("*?#", *p) == 0)
- {
- if (!findchar(s, slen, *p))
- return 0;
- }
- #endif
- while (*w)
- {
- if (matching(s, w, slen))
- return 1;
- if (slen == 0 || *s == 0)
- break;
- s++;
- slen--;
- }
- break;
- }
- else
- return 0;
- }
- if (*w != 0)
- return 0;
- if (slen != 0 && *s != 0)
- return 0;
- return 1;
- }
-
- char curfilename[128] = "";
-
- char* trivial[] =
- {
- "ACOU*PIANO",
- "BASS",
- "BASOON",
- "BELL*",
- "BRASS",
- "CYMBAL*",
- "*DRUM*",
- "CELLO",
- "CHOIR",
- "CLARINET",
- "CONTRABASS",
- "E*GUITAR",
- "E*PIANO",
- "FL?CHE",
- "FLUTE",
- "FRENCH*HORN",
- "FUNKYGIT",
- "GITARRE",
- "GLOCKENSPIEL",
- "GUITAR",
- "HIHAT",
- "HI?HAT",
- "JAZZ*GUITAR",
- "MELODIE",
- "MELODY",
- "MIDI",
- "MUTE*G*TAR*",
- "ORCH*HIT",
- "*ORGAN",
- "*ORGEL",
- "PERCUSSION",
- "PIANO",
- "PIANO*LEFT",
- "PIANO*RIGHT",
- "PIZZICATO",
- "POLYSYNTH",
- "SANTUR",
- "SAX",
- "SLOW*STR*",
- "SNARE",
- "SOLO*G*TAR*",
- "STRINGS",
- "SYNTH*B*ASS",
- "TIMPANI",
- "TOMS",
- "TRACK",
- "TROMBONE*",
- "TRUMPET*",
- "TUBA",
- "VIOLIN*",
- "VOCAL*",
- "VOICE*",
- NULL
- };
-
- int trivialtext(unsigned char* s, unsigned len)
- {
- static unsigned char buf[256];
- int i;
-
- while (len > 0 && !isalpha(*s))
- {
- s++; len--;
- }
- if (len >= sizeof(buf))
- return 0;
- for (i = 0; i < len; i++)
- {
- if (isalpha(s[i]))
- buf[i] = s[i];
- else
- buf[i] = ' ';
- }
- while (len > 0 && !isalpha(buf[len-1]))
- buf[--len]= 0;
-
- if (len == 0)
- return 0;
-
- for (char**t = trivial; *t; t++)
- if (matching(buf, *t, len))
- return 1;
- return 0;
- }
-
- void findstr(unsigned char* s, unsigned len, char* search, int searchlen)
- {
- static char subsearch[256];
-
- subsearch[0] = '*';
- strcpy(subsearch+1, search);
- strcat(subsearch, "*");
-
- if (matching(s, subsearch, len))
- {
- if (!trivialcheck || !trivialtext(s, len))
- {
- const char* longname;
-
- #if defined(__MSDOS__) && defined(GNDIR)
- longname = getlongfilename(curfilename);
- if (!longname)
- longname = curfilename;
- #else
- longname = curfilename;
- #endif
- printf("%s: %*.*s\n", longname, len, len, s);
- }
- }
- }
-
- // meta = 0xff [1-15] len char[len]
- int findmeta(unsigned char* s, unsigned len, char* search, int searchlen)
- {
- while (len > 0)
- {
- unsigned char* ff = (unsigned char*)memchr(s, 0xff, len);
- if (!ff)
- break;
- ff++;
- len -= unsigned(ff - s);
- s = ff;
- if (len > 0 && *s <= 15 && *s >= 1 && s[1] < 0x80)
- {
- // s[0] == 1-15 s[1] == len s[2..] == text
- if (len < s[1] + 2)
- return len + 1;
- findstr(s+2, s[1], search, searchlen);
- }
- }
- return 0;
- }
-
- void findfile(FILE* f, long filesize, char* search, int searchlen)
- {
- static unsigned char buf[SEARCHBUFSIZE];
- unsigned buflen = 0;
-
- while (1)
- {
- // memset(buf+buflen, 0, sizeof(buf)-buflen);
- unsigned n = sizeof(buf) - buflen;
- if (filesize - ftell(f) < n)
- n = (unsigned)(filesize-ftell(f));
- if (fread(buf + buflen, n, 1, f) != 1)
- break;
- buflen += n;
- n = findmeta(buf, buflen, search, searchlen);
- if (n > 0)
- {
- memmove(buf, buf + buflen - n, n);
- buflen = n;
- }
- else
- buflen = 0;
- }
- }
-
- void findfile(char* filename, char* search, int searchlen)
- {
- FILE* f;
-
- f = fopen(filename, READ_BINARY);
- if (!f)
- {
- perror(filename);
- return;
- }
- fseek(f, 0, SEEK_END);
- long filesize = ftell(f);
- rewind(f);
-
- // puts(filename);
- // puts(search);
- strcpy(curfilename, filename);
- findfile(f, filesize, search, searchlen);
- fclose(f);
- }
-
- #ifdef __MSDOS__
- // get filenames containing wildcards *, ?
- #include <dir.h>
- #include <dos.h>
- void findlist(char* filelist, char* search, int searchlen)
- {
- if (strchr(filelist, '*') == 0 && strchr(filelist, '?') == 0)
- findfile(filelist, search, searchlen);
- else
- {
- struct ffblk dir;
- int done = findfirst(filelist, &dir, FA_RDONLY+FA_ARCH);
-
- char fullname[128], *p;
-
- p = strrchr(filelist, '\\');
- if (!p)
- p = strchr(filelist, ':');
- if (p)
- {
- strncpy(fullname, filelist, p - filelist+1);
- p = fullname + (p-filelist)+1;
- }
- else
- p = fullname;
- while (!done)
- {
- if ((dir.ff_attrib & (FA_DIREC+FA_HIDDEN+FA_LABEL+FA_SYSTEM)) == 0)
- {
- strcpy(p, dir.ff_name);
- findfile(fullname, search, searchlen);
- }
- done = findnext(&dir);
- }
- }
- }
- #endif
-
- void usage()
- {
- fprintf(stderr, "midifind search files.mid ...\n");
- return;
- }
-
- void main(int argc, char** argv)
- {
- char* name;
-
- argc--; argv++;
- while (argc > 0 && **argv == '-')
- {
- if (strncmp(*argv, "-trivial", 2) == 0)
- {
- trivialcheck = 1;
- argc--; argv++; continue;
- }
- fprintf(stderr, "invalid option: %s\n", *argv);
- argc--; argv++;
- }
- if (!argc)
- usage();
-
- char * search = *argv++; argc--;
-
- #ifdef __MSDOS__
- if (!argc)
- findlist("*.mid", search, strlen(search));
- #else
- if (!argc)
- usage();
- #endif
-
- while (argc-- > 0)
- {
- name = *argv++;
- #ifdef __MSDOS__
- findlist(name, search, strlen(search));
- #else
- findfile(name, search, strlen(search));
- #endif
- }
- }
-